package com.huawang.mdesign.model.service.model.core;

import com.huawang.business.service.model.base.ElementCheckService;
import com.huawang.business.service.model.core.InternalUmlService;
import com.huawang.core.definition.mof.UMLDefinitionConstants;
import com.huawang.core.definition.mof.instances.MetaClassInstance;
import com.huawang.core.semantics.constants.TypeEnum;
import com.huawang.mdesign.model.service.constant.SpringBeanNameConstants;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

@Service(SpringBeanNameConstants.INTERNAL_SPECIFICATION_SERVICE)
@Primary
public class UAFInternalSpecificationService extends com.huawang.business.service.model.core.InternalSpecificationService {
    @Autowired
    private ElementCheckService elementCheckService;

    @Autowired
    private InternalUmlService internalUmlService;

    /**
     * 根据type获取对应的specification类型
     *
     * @return java.lang.String
     * @author xz
     * @date 2024/02/04 13:48
     */
    @Override
    @NotNull
    public String getValuespecificationType(String projectId, MetaClassInstance type) {
        if (type == null) {
            return UMLDefinitionConstants.LiteralString;
        }
        if (internalUmlService.isMetaClass(projectId, type) || internalUmlService.checkInstanceType(projectId, type,
                UMLDefinitionConstants.Stereotype)) {
            return handleStereotype(projectId, type);
        } else {
            return handleNonStereotype(projectId, type);
        }
    }

    /**
     * 处理构造型
     *
     * @param projectId
     * @param type
     * @return
     */
    @NotNull
    private String handleStereotype(String projectId, MetaClassInstance type) {
        if(internalUmlService.getBaseClassList(projectId, type).stream().anyMatch(UMLDefinitionConstants.LiteralString::equals)) {
            return UMLDefinitionConstants.LiteralString;
        } else {
            return UMLDefinitionConstants.ElementValue;
        }
    }

    /**
     * 处理非构造型
     *
     * @param projectId
     * @param type
     * @return
     */
    @NotNull
    private String handleNonStereotype(String projectId, MetaClassInstance type) {
        if (elementCheckService.checkPrimitiveType(projectId, type, TypeEnum.STRING)) {
            return UMLDefinitionConstants.LiteralString;
        } else if (elementCheckService.checkPrimitiveType(projectId, type, TypeEnum.INTEGER)) {
            return UMLDefinitionConstants.LiteralInteger;
        } else if (elementCheckService.checkPrimitiveType(projectId, type, TypeEnum.UNLIMITEDNATURAL)) {
            return UMLDefinitionConstants.LiteralUnlimitedNatural;
        } else if (elementCheckService.checkPrimitiveType(projectId, type, TypeEnum.REAL)) {
            return UMLDefinitionConstants.LiteralReal;
        } else if (elementCheckService.checkPrimitiveType(projectId, type, TypeEnum.BOOLEAN)) {
            return UMLDefinitionConstants.LiteralBoolean;
        } else if (internalUmlService.checkInstanceType(projectId, type, UMLDefinitionConstants.Enumeration)) {
            return UMLDefinitionConstants.InstanceValue;
        } else if (internalUmlService.checkInstanceType(projectId, type, UMLDefinitionConstants.DataType)) {
            return handleDataType(projectId, type);
        } else {
            return UMLDefinitionConstants.InstanceValue;
        }
    }

    /**
     * 处理DataType
     *
     * @param projectId
     * @param type
     * @return
     */
    @NotNull
    private String handleDataType(String projectId, MetaClassInstance type) {
        if (internalUmlService.checkInstanceType(projectId, type, UMLDefinitionConstants.SysML_ValueType)) {
            // 这3个UAF元模型继承了SysML的ValueType，当它们作为属性的类型的时候，需要以实例被选择
            if(internalUmlService.checkInstanceType(projectId, type, UMLDefinitionConstants.UAF_MeasurementSet) ||
                    internalUmlService.checkInstanceType(projectId, type, UMLDefinitionConstants.UAF_Condition) ||
                    internalUmlService.checkInstanceType(projectId, type, UMLDefinitionConstants.UAF_StatusIndicators)) {
                return UMLDefinitionConstants.InstanceValue;
            } else {
                return UMLDefinitionConstants.LiteralReal;
            }
        } else {
            return UMLDefinitionConstants.LiteralString;
        }
    }
}
